package documents;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import java.util.Set;

import org.ejml.simple.SimpleMatrix;

import utils.IStemmer;

public class ReutersTrainingDocumentCollection implements IDocumentCollection {
   private static String[] FILE_NAMES = {
         "data/sampleTrainingSet.sgm"/*,
                                     "data/reut2-000.sgm", 
                                     "data/reut2-001.sgm", 
                                     "data/reut2-002.sgm", 
                                     "data/reut2-003.sgm", 
                                     "data/reut2-004.sgm", 
                                     "data/reut2-005.sgm", 
                                     "data/reut2-006.sgm", 
                                     "data/reut2-007.sgm", 
                                     "data/reut2-008.sgm", 
                                     "data/reut2-009.sgm", 
                                     "data/reut2-010.sgm", 
                                     "data/reut2-011.sgm", 
                                     "data/reut2-012.sgm", 
                                     "data/reut2-013.sgm", 
                                     "data/reut2-014.sgm", 
                                     "data/reut2-015.sgm", 
                                     "data/reut2-016.sgm", 
                                     "data/reut2-017.sgm", 
                                     "data/reut2-018.sgm", 
                                     "data/reut2-019.sgm", 
                                     "data/reut2-020.sgm", 
                                     "data/reut2-021.sgm"*/};
   
   protected static final String T_START = "<TITLE>";
   protected static final String T_END = "</TITLE>";
   protected static final String B_START = "<BODY>";
   protected static final String B_END = "</BODY>";
   
   protected final IStemmer stemmer;
   protected final Set<String> stopWords;
   protected final String breakRegEx;
   
   protected SimpleMatrix simpleMatrix;
   protected List<String> documentList;
   protected List<String> wordList;
   
   public ReutersTrainingDocumentCollection(final Set<String> stopWords, final IStemmer stemmer, final String breakRegEx) {
      this.stemmer = stemmer;
      this.stopWords = stopWords;
      this.breakRegEx = breakRegEx;
      initialize();
   }
   
   @Override
   public List<String> getDocumentList() {
      return documentList;
   }
   
   @Override
   public List<String> getWordList() {
      return wordList;
   }
   
   @Override
   public SimpleMatrix getMatrix() {
      return simpleMatrix;
   }
   
   private void initialize() {
      try {
         final BuildMatrix bm = new BuildMatrix();
         
         byte mode = 0;//0 - searching for title, 1 - reading title, 2 - searching for content, 3 - reading content
         int fileIndex = 0;
         String tape = "";
         for (fileIndex = 0; fileIndex < FILE_NAMES.length; ++fileIndex) {
            final BufferedReader reader = new BufferedReader(new FileReader(FILE_NAMES[fileIndex]));
            String b;
            while ((b = reader.readLine()) != null) {
               while (b != null && b.length() > 0) {
                  if (mode == 2 && b.indexOf(T_START) != -1) {
                     bm.trashTitle();
                     mode = 0;
                  }
                  if (mode == 0) {
                     final int start = b.indexOf(T_START);
                     final int end = b.indexOf(T_END);
                     if (start != -1 && end != -1) {
                        bm.startTitle(b.substring(start + T_START.length(), end));
                        mode = 2;
                        b = b.substring(end + T_END.length());
                     }
                     else if (start != -1) {
                        tape = b.substring(start + T_START.length());
                        mode = 1;
                        b = null;
                     }
                     else if (end != -1) {
                        throw new RuntimeException("found an end without a start");
                     }
                     else {
                        b = null;
                     }
                  }
                  else if (mode == 1) {
                     final int end = b.indexOf(T_END);
                     if (end != -1) {
                        tape = tape.concat(" ");
                        tape = tape.concat(b.substring(0, end));
                        bm.startTitle(tape);
                        mode = 2;
                        b = b.substring(end + T_END.length());
                     }
                     else {
                        tape = tape.concat(b);
                        b = null;
                     }
                  }
                  else if (mode == 2) {
                     final int start = b.indexOf(B_START);
                     final int end = b.indexOf(B_END);
                     if (start != -1 && end != -1) {
                        breakWordsForBM(b.substring(start + B_START.length(), end), bm);
                        mode = 0;
                        b = b.substring(end + B_END.length());
                     }
                     else if (start != -1) {
                        breakWordsForBM(b.substring(start + B_START.length()), bm);
                        mode = 3;
                        b = null;
                     }
                     else if (end != -1) {
                        throw new RuntimeException("found an end without a start");
                     }
                     else {
                        b = null;
                     }
                  }
                  else if (mode == 3) {
                     final int end = b.indexOf(B_END);
                     if (end != -1) {
                        breakWordsForBM(b.substring(0, end), bm);
                        mode = 0;
                        b = b.substring(end + B_END.length());
                     }
                     else {
                        breakWordsForBM(b, bm);
                        b = null;
                     }
                  }
               }
            }
            reader.close();
         }//MAYNEED TO CHANGE THE FALSE
         simpleMatrix = bm.buildSimpleMatrix(false);
         wordList = bm.getWordList();
         documentList = bm.getTitles();
      }
      catch (final FileNotFoundException e) {
         e.printStackTrace();
      }
      catch (final IOException e) {
         e.printStackTrace();
      }
   }
   
   protected void breakWordsForBM(final String str, final BuildMatrix bm) {
      final String[] words = str.split(breakRegEx);
      for (final String word2 : words) {
         if (word2.length() == 0) {
            continue;
         }
         final String word = stemmer.stemWord(word2.toLowerCase());
         if (!stopWords.contains(word)) {
            bm.addWord(word);
         }
      }
   }
   
}
